package br.com.uniban.entity;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

import org.eclipse.persistence.annotations.PrivateOwned;

@NamedQueries({ @NamedQuery(name = "Prova.numberOfProva", query = "select COUNT(p) from Prova p") ,
				@NamedQuery(name = "Prova.pending", query = "select p from Prova p where p.flAtiva = false"),
				@NamedQuery(name = "Prova.criadas", query = "select p from Prova p where p.usuario.id = :idCriador")
				})
@Entity
@Table(name = "tb_prova")
public class Prova implements Serializable {

	@Transient
	private static final long serialVersionUID = 1L;
	@Transient
	public final static Character FACIL = 'F';
	@Transient
	public final static Character MEDIO = 'M';
	@Transient
	public final static Character DIFICIL = 'D';

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "id_prova")
	private Integer id;

	@Column(nullable = false, length = 150)
	private String nome;

	@Column(length = 150)
	private String descricao;

	@Temporal(TemporalType.DATE)
	private Date publicacao;

	@Column(nullable = false, length = 1)
	private Character nivel;

	@OneToOne(optional = true, fetch = FetchType.LAZY)
	@JoinColumn(name = "id_usuario", referencedColumnName = "id_usuario")
	private Usuario usuario;

	@OneToOne(optional = true, fetch = FetchType.LAZY, cascade = {CascadeType.MERGE,CascadeType.REFRESH})
	@JoinColumn(name = "id_disciplina", referencedColumnName = "id_disciplina")
	private Disciplina disciplina;

	@OneToMany(fetch = FetchType.EAGER, mappedBy = "prova",cascade=CascadeType.ALL)
	@PrivateOwned
	private List<ProvaQuestao> listaDeQuestoes;
	
	@Column(name = "fl_ativa")
	private Boolean flAtiva;
	
	@OneToOne(mappedBy="prova")
	private ProvaRespondida provaResp;

	public Prova() {
	}

	public Prova(String nome, String descricao, Date publicacao,
			Character nivel, Usuario usuario, Disciplina disciplina) {
		super();
		this.nome = nome;
		this.descricao = descricao;
		this.publicacao = publicacao;
		this.nivel = nivel;
		this.usuario = usuario;
		this.disciplina = disciplina;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public String getDescricao() {
		return descricao;
	}

	public void setDescricao(String descricao) {
		this.descricao = descricao;
	}

	public Date getPublicacao() {
		return publicacao;
	}

	public void setPublicacao(Date publicacao) {
		this.publicacao = publicacao;
	}

	public Character getNivel() {
		return nivel;
	}

	public void setNivel(Character nivel) {
		this.nivel = nivel;
	}

	public Usuario getUsuario() {
		return usuario;
	}

	public void setUsuario(Usuario usuario) {
		this.usuario = usuario;
	}

	public Disciplina getDisciplina() {
		return disciplina;
	}

	public void setDisciplina(Disciplina disciplina) {
		this.disciplina = disciplina;
	}



	public Boolean getFlAtiva() {
		return flAtiva;
	}

	public void setFlAtiva(Boolean flAtiva) {
		this.flAtiva = flAtiva;
	}

	public ProvaRespondida getProvaResp() {
		return provaResp;
	}

	public void setProvaResp(ProvaRespondida provaResp) {
		this.provaResp = provaResp;
	}

	public List<ProvaQuestao> getListaDeQuestoes() {
		return listaDeQuestoes;
	}

	public void setListaDeQuestoes(List<ProvaQuestao> listaDeQuestoes) {
		this.listaDeQuestoes = listaDeQuestoes;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((descricao == null) ? 0 : descricao.hashCode());
		result = prime * result
				+ ((disciplina == null) ? 0 : disciplina.hashCode());
		result = prime * result + ((flAtiva == null) ? 0 : flAtiva.hashCode());
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		result = prime * result + ((nivel == null) ? 0 : nivel.hashCode());
		result = prime * result + ((nome == null) ? 0 : nome.hashCode());
		result = prime * result
				+ ((provaResp == null) ? 0 : provaResp.hashCode());
		result = prime * result
				+ ((publicacao == null) ? 0 : publicacao.hashCode());
		result = prime * result + ((usuario == null) ? 0 : usuario.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Prova other = (Prova) obj;
		if (descricao == null) {
			if (other.descricao != null)
				return false;
		} else if (!descricao.equals(other.descricao))
			return false;
		if (disciplina == null) {
			if (other.disciplina != null)
				return false;
		} else if (!disciplina.equals(other.disciplina))
			return false;
		if (flAtiva == null) {
			if (other.flAtiva != null)
				return false;
		} else if (!flAtiva.equals(other.flAtiva))
			return false;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		if (nivel == null) {
			if (other.nivel != null)
				return false;
		} else if (!nivel.equals(other.nivel))
			return false;
		if (nome == null) {
			if (other.nome != null)
				return false;
		} else if (!nome.equals(other.nome))
			return false;
		if (provaResp == null) {
			if (other.provaResp != null)
				return false;
		} else if (!provaResp.equals(other.provaResp))
			return false;
		if (publicacao == null) {
			if (other.publicacao != null)
				return false;
		} else if (!publicacao.equals(other.publicacao))
			return false;
		if (usuario == null) {
			if (other.usuario != null)
				return false;
		} else if (!usuario.equals(other.usuario))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "Prova [id=" + id + ", nome=" + nome + ", descricao="
				+ descricao + ", publicacao=" + publicacao + ", nivel=" + nivel
				+ ", usuario=" + usuario + ", disciplina=" + disciplina
				+ ", flAtiva=" + flAtiva + ", provaResp=" + provaResp + "]";
	}

}
